{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "69442147",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import os\n",
    "import tqdm\n",
    "from tensorflow.keras.models import Sequential\n",
    "from tensorflow.keras.layers import Dense, LSTM, Dropout\n",
    "from tensorflow.keras.callbacks import ModelCheckpoint, TensorBoard, EarlyStopping\n",
    "from sklearn.model_selection import train_test_split"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "fb339314",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>filename</th>\n",
       "      <th>gender</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>data/cv-other-train/sample-069205.npy</td>\n",
       "      <td>female</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>data/cv-valid-train/sample-063134.npy</td>\n",
       "      <td>female</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>data/cv-other-train/sample-080873.npy</td>\n",
       "      <td>female</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>data/cv-other-train/sample-105595.npy</td>\n",
       "      <td>female</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>data/cv-valid-train/sample-144613.npy</td>\n",
       "      <td>female</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                filename  gender\n",
       "0  data/cv-other-train/sample-069205.npy  female\n",
       "1  data/cv-valid-train/sample-063134.npy  female\n",
       "2  data/cv-other-train/sample-080873.npy  female\n",
       "3  data/cv-other-train/sample-105595.npy  female\n",
       "4  data/cv-valid-train/sample-144613.npy  female"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.read_csv(\"balanced-all.csv\")\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "05f99970",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total samples: 66938\n",
      "Total male samples: 33469\n",
      "Total female samples: 33469\n"
     ]
    }
   ],
   "source": [
    "# 得到总样本量\n",
    "n_samples = len(df)\n",
    "# 得到总的男性样本量\n",
    "n_male_samples = len(df[df['gender'] == 'male'])\n",
    "# 得到总的女性样本量\n",
    "n_female_samples = len(df[df['gender'] == 'female'])\n",
    "print(\"Total samples:\", n_samples)\n",
    "print(\"Total male samples:\", n_male_samples)\n",
    "print(\"Total female samples:\", n_female_samples)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "f756cd34",
   "metadata": {},
   "outputs": [],
   "source": [
    "label2int = {\n",
    "    \"male\": 1,\n",
    "    \"female\": 0\n",
    "}\n",
    "\n",
    "def load_data(vector_length=128):\n",
    "    df = pd.read_csv(\"balanced-all.csv\")\n",
    "    n_samples = len(df)\n",
    "    n_male_samples = len(df[df['gender'] == 'male'])\n",
    "    n_female_samples = len(df[df['gender'] == 'female'])\n",
    "    print(\"Total samples:\", n_samples)\n",
    "    print(\"Total male samples:\", n_male_samples)\n",
    "    print(\"Total female samples:\", n_female_samples)\n",
    "    # x存储音频特征\n",
    "    X = np.zeros((n_samples, vector_length))\n",
    "    # y存储标签，1为男性，0为女性\n",
    "    y = np.zeros((n_samples, 1))\n",
    "    for i, (filename, gender) in tqdm.tqdm(enumerate(zip(df['filename'], df['gender'])), \"Loading data\", total=n_samples):\n",
    "        features = np.load(filename)\n",
    "        X[i] = features\n",
    "        y[i] = label2int[gender]\n",
    "    return X, y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "6d49c27e",
   "metadata": {},
   "outputs": [],
   "source": [
    "def split_data(X, y, test_size=0.1, valid_size=0.1):\n",
    "    # 拆分训练集和测试集\n",
    "    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size, random_state=7)\n",
    "    # 拆分训练集和验证集\n",
    "    X_train, X_valid, y_train, y_valid = train_test_split(X_train, y_train, test_size=valid_size, random_state=7)\n",
    "    return {\n",
    "        \"X_train\": X_train,\n",
    "        \"X_valid\": X_valid,\n",
    "        \"X_test\": X_test,\n",
    "        \"y_train\": y_train,\n",
    "        \"y_valid\": y_valid,\n",
    "        \"y_test\": y_test\n",
    "    }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "290c0ba3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total samples: 66938\n",
      "Total male samples: 33469\n",
      "Total female samples: 33469\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Loading data: 100%|████████████████████████████████████████████████████████████| 66938/66938 [00:49<00:00, 1340.86it/s]\n"
     ]
    }
   ],
   "source": [
    "# 加载数据集\n",
    "X, y = load_data()\n",
    "# 将数据拆分为训练集、验证集和测试集\n",
    "data = split_data(X, y, test_size=0.1, valid_size=0.1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "136297c8",
   "metadata": {},
   "outputs": [],
   "source": [
    "#3个隐藏层的FNN\n",
    "def create_model(vector_length=128):\n",
    "    model = Sequential()\n",
    "    model.add(Dense(256, input_shape=(vector_length,)))\n",
    "    model.add(Dense(128, activation=\"relu\"))\n",
    "    model.add(Dense(64, activation=\"relu\"))\n",
    "    # 激活函数-sigmoid 0表示女，1表示男\n",
    "    model.add(Dense(1, activation=\"sigmoid\"))\n",
    "    # 损失函数使用binary_crossentropy，优化器使用adam\n",
    "    model.compile(loss=\"binary_crossentropy\", metrics=[\"accuracy\"], optimizer=\"adam\")\n",
    "    # 显示模型\n",
    "    model.summary()\n",
    "    return model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "03cd3a70",
   "metadata": {},
   "outputs": [],
   "source": [
    "#4个隐藏层的FNN\n",
    "def create_model(vector_length=128):\n",
    "    model = Sequential()\n",
    "    model.add(Dense(256, input_shape=(vector_length,)))\n",
    "    model.add(Dense(128, activation=\"relu\"))\n",
    "    model.add(Dense(64, activation=\"relu\"))\n",
    "    model.add(Dense(32, activation=\"relu\"))\n",
    "    # 激活函数-sigmoid 0表示女，1表示男\n",
    "    model.add(Dense(1, activation=\"sigmoid\"))\n",
    "    # 损失函数使用binary_crossentropy，优化器使用adam\n",
    "    model.compile(loss=\"binary_crossentropy\", metrics=[\"accuracy\"], optimizer=\"adam\")\n",
    "    # 显示模型\n",
    "    model.summary()\n",
    "    return model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "93f2ada5",
   "metadata": {},
   "outputs": [],
   "source": [
    "#5个隐藏层的FNN\n",
    "def create_model(vector_length=128):\n",
    "    model = Sequential()\n",
    "    model.add(Dense(256, input_shape=(vector_length,)))\n",
    "    model.add(Dense(128, activation=\"relu\"))\n",
    "    model.add(Dense(64, activation=\"relu\"))\n",
    "    model.add(Dense(32, activation=\"relu\"))\n",
    "    model.add(Dense(16, activation=\"relu\"))\n",
    "    # 激活函数-sigmoid 0表示女，1表示男\n",
    "    model.add(Dense(1, activation=\"sigmoid\"))\n",
    "    # 损失函数使用binary_crossentropy，优化器使用adam\n",
    "    model.compile(loss=\"binary_crossentropy\", metrics=[\"accuracy\"], optimizer=\"adam\")\n",
    "    # 显示模型\n",
    "    model.summary()\n",
    "    return model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "780c72cb",
   "metadata": {},
   "outputs": [],
   "source": [
    "#5个隐藏层的FNN,添加了dropout\n",
    "def create_model(vector_length=128):\n",
    "    model = Sequential()\n",
    "    model.add(Dense(256, input_shape=(vector_length,)))\n",
    "    model.add(Dropout(0.1))\n",
    "    model.add(Dense(128, activation=\"relu\"))\n",
    "    model.add(Dropout(0.1))\n",
    "    model.add(Dense(64, activation=\"relu\"))\n",
    "    model.add(Dropout(0.1))\n",
    "    model.add(Dense(32, activation=\"relu\"))\n",
    "    model.add(Dropout(0.1))\n",
    "    model.add(Dense(16, activation=\"relu\"))\n",
    "    model.add(Dropout(0.1))\n",
    "    # 激活函数-sigmoid 0表示女，1表示男\n",
    "    model.add(Dense(1, activation=\"sigmoid\"))\n",
    "    # 损失函数使用binary_crossentropy，优化器使用adam\n",
    "    model.compile(loss=\"binary_crossentropy\", metrics=[\"accuracy\"], optimizer=\"adam\")\n",
    "    # 显示模型\n",
    "    model.summary()\n",
    "    return model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "58f3b01a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      " Layer (type)                Output Shape              Param #   \n",
      "=================================================================\n",
      " dense (Dense)               (None, 256)               33024     \n",
      "                                                                 \n",
      " dropout (Dropout)           (None, 256)               0         \n",
      "                                                                 \n",
      " dense_1 (Dense)             (None, 128)               32896     \n",
      "                                                                 \n",
      " dropout_1 (Dropout)         (None, 128)               0         \n",
      "                                                                 \n",
      " dense_2 (Dense)             (None, 64)                8256      \n",
      "                                                                 \n",
      " dropout_2 (Dropout)         (None, 64)                0         \n",
      "                                                                 \n",
      " dense_3 (Dense)             (None, 32)                2080      \n",
      "                                                                 \n",
      " dropout_3 (Dropout)         (None, 32)                0         \n",
      "                                                                 \n",
      " dense_4 (Dense)             (None, 16)                528       \n",
      "                                                                 \n",
      " dropout_4 (Dropout)         (None, 16)                0         \n",
      "                                                                 \n",
      " dense_5 (Dense)             (None, 1)                 17        \n",
      "                                                                 \n",
      "=================================================================\n",
      "Total params: 76,801\n",
      "Trainable params: 76,801\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "# 创建模型\n",
    "model = create_model()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "6ca2a225",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/100\n",
      "848/848 [==============================] - 5s 4ms/step - loss: 0.4927 - accuracy: 0.7939 - val_loss: 0.3842 - val_accuracy: 0.8350\n",
      "Epoch 2/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.3796 - accuracy: 0.8487 - val_loss: 0.3419 - val_accuracy: 0.8624\n",
      "Epoch 3/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.3425 - accuracy: 0.8664 - val_loss: 0.2995 - val_accuracy: 0.8807\n",
      "Epoch 4/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.3202 - accuracy: 0.8768 - val_loss: 0.2770 - val_accuracy: 0.8895\n",
      "Epoch 5/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.3084 - accuracy: 0.8803 - val_loss: 0.2731 - val_accuracy: 0.8906\n",
      "Epoch 6/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2895 - accuracy: 0.8883 - val_loss: 0.2643 - val_accuracy: 0.8961\n",
      "Epoch 7/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2794 - accuracy: 0.8926 - val_loss: 0.2470 - val_accuracy: 0.9046\n",
      "Epoch 8/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2731 - accuracy: 0.8946 - val_loss: 0.2481 - val_accuracy: 0.9064\n",
      "Epoch 9/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2682 - accuracy: 0.8968 - val_loss: 0.2493 - val_accuracy: 0.9009\n",
      "Epoch 10/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2619 - accuracy: 0.9003 - val_loss: 0.2427 - val_accuracy: 0.9084\n",
      "Epoch 11/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2595 - accuracy: 0.9012 - val_loss: 0.2393 - val_accuracy: 0.9109\n",
      "Epoch 12/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2570 - accuracy: 0.9019 - val_loss: 0.2287 - val_accuracy: 0.9152\n",
      "Epoch 13/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2453 - accuracy: 0.9064 - val_loss: 0.2451 - val_accuracy: 0.9154\n",
      "Epoch 14/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2496 - accuracy: 0.9059 - val_loss: 0.2394 - val_accuracy: 0.9064\n",
      "Epoch 15/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2436 - accuracy: 0.9081 - val_loss: 0.2291 - val_accuracy: 0.9172\n",
      "Epoch 16/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2386 - accuracy: 0.9083 - val_loss: 0.2272 - val_accuracy: 0.9152\n",
      "Epoch 17/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2356 - accuracy: 0.9116 - val_loss: 0.2202 - val_accuracy: 0.9227\n",
      "Epoch 18/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2365 - accuracy: 0.9116 - val_loss: 0.2314 - val_accuracy: 0.9163\n",
      "Epoch 19/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2333 - accuracy: 0.9124 - val_loss: 0.2210 - val_accuracy: 0.9193\n",
      "Epoch 20/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2284 - accuracy: 0.9127 - val_loss: 0.2194 - val_accuracy: 0.9197\n",
      "Epoch 21/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2233 - accuracy: 0.9168 - val_loss: 0.2231 - val_accuracy: 0.9178\n",
      "Epoch 22/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2255 - accuracy: 0.9146 - val_loss: 0.2130 - val_accuracy: 0.9213\n",
      "Epoch 23/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2205 - accuracy: 0.9170 - val_loss: 0.2236 - val_accuracy: 0.9185\n",
      "Epoch 24/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2232 - accuracy: 0.9161 - val_loss: 0.2486 - val_accuracy: 0.9095\n",
      "Epoch 25/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2238 - accuracy: 0.9164 - val_loss: 0.2218 - val_accuracy: 0.9202\n",
      "Epoch 26/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2161 - accuracy: 0.9178 - val_loss: 0.2152 - val_accuracy: 0.9180\n",
      "Epoch 27/100\n",
      "848/848 [==============================] - 3s 3ms/step - loss: 0.2164 - accuracy: 0.9181 - val_loss: 0.2174 - val_accuracy: 0.9185\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<keras.callbacks.History at 0x2356d489850>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用tensorboard查看查看模型在训练期间的损失和准确性\n",
    "tensorboard = TensorBoard(log_dir=\"logs\")\n",
    "# 连续5次训练结果没有更好，就停止训练，将 restore_best_weights 设置为 True 将把训练期间记录的最佳权重分配给模型权重。\n",
    "early_stopping = EarlyStopping(mode=\"min\", patience=5, restore_best_weights=True)\n",
    "\n",
    "batch_size = 64\n",
    "epochs = 100\n",
    "# 使用训练集训练模型并使用验证集进行验证\n",
    "model.fit(data[\"X_train\"], data[\"y_train\"], epochs=epochs, batch_size=batch_size, validation_data=(data[\"X_valid\"], data[\"y_valid\"]),\n",
    "          callbacks=[tensorboard, early_stopping])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "fd037855",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 保存模型\n",
    "model.save(\"results/model.h5\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "a3f83bae",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "使用 6694 个样本评估模型。。。\n",
      "Loss: 0.2082\n",
      "Accuracy: 92.22%\n"
     ]
    }
   ],
   "source": [
    "# 使用测试集评估模型\n",
    "print(f\"使用 {len(data['X_test'])} 个样本评估模型。。。\")\n",
    "loss, accuracy = model.evaluate(data[\"X_test\"], data[\"y_test\"], verbose=0)\n",
    "print(f\"Loss: {loss:.4f}\")\n",
    "print(f\"Accuracy: {accuracy*100:.2f}%\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "a2e9acf8",
   "metadata": {},
   "outputs": [],
   "source": [
    "import librosa\n",
    "import numpy as np\n",
    "\n",
    "def extract_feature(file_name, **kwargs):\n",
    "    \"\"\"\n",
    "    从音频文件“file_name”中提取特征:\n",
    "            - MFCC (mfcc)\n",
    "            - 色度 (chroma)\n",
    "            - 梅尔频率倒谱系数  (mel)\n",
    "            - 对比度 (contrast)\n",
    "            - 色调质心特征 (tonnetz)\n",
    "        \n",
    "    \"\"\"\n",
    "    mfcc = kwargs.get(\"mfcc\")\n",
    "    chroma = kwargs.get(\"chroma\")\n",
    "    mel = kwargs.get(\"mel\")\n",
    "    contrast = kwargs.get(\"contrast\")\n",
    "    tonnetz = kwargs.get(\"tonnetz\")\n",
    "    X, sample_rate = librosa.core.load(file_name)\n",
    "    if chroma or contrast:\n",
    "        stft = np.abs(librosa.stft(X))\n",
    "    result = np.array([])\n",
    "    if mfcc:\n",
    "        mfccs = np.mean(librosa.feature.mfcc(y=X, sr=sample_rate, n_mfcc=40).T, axis=0)\n",
    "        result = np.hstack((result, mfccs))\n",
    "    if chroma:\n",
    "        chroma = np.mean(librosa.feature.chroma_stft(S=stft, sr=sample_rate).T,axis=0)\n",
    "        result = np.hstack((result, chroma))\n",
    "    if mel:\n",
    "        mel = np.mean(librosa.feature.melspectrogram(X, sr=sample_rate).T,axis=0)\n",
    "        result = np.hstack((result, mel))\n",
    "    if contrast:\n",
    "        contrast = np.mean(librosa.feature.spectral_contrast(S=stft, sr=sample_rate).T,axis=0)\n",
    "        result = np.hstack((result, contrast))\n",
    "    if tonnetz:\n",
    "        tonnetz = np.mean(librosa.feature.tonnetz(y=librosa.effects.harmonic(X), sr=sample_rate).T,axis=0)\n",
    "        result = np.hstack((result, tonnetz))\n",
    "    return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "dcc5aaa6",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential_1\"\n",
      "_________________________________________________________________\n",
      " Layer (type)                Output Shape              Param #   \n",
      "=================================================================\n",
      " dense_6 (Dense)             (None, 256)               33024     \n",
      "                                                                 \n",
      " dropout_5 (Dropout)         (None, 256)               0         \n",
      "                                                                 \n",
      " dense_7 (Dense)             (None, 128)               32896     \n",
      "                                                                 \n",
      " dropout_6 (Dropout)         (None, 128)               0         \n",
      "                                                                 \n",
      " dense_8 (Dense)             (None, 64)                8256      \n",
      "                                                                 \n",
      " dropout_7 (Dropout)         (None, 64)                0         \n",
      "                                                                 \n",
      " dense_9 (Dense)             (None, 32)                2080      \n",
      "                                                                 \n",
      " dropout_8 (Dropout)         (None, 32)                0         \n",
      "                                                                 \n",
      " dense_10 (Dense)            (None, 16)                528       \n",
      "                                                                 \n",
      " dropout_9 (Dropout)         (None, 16)                0         \n",
      "                                                                 \n",
      " dense_11 (Dense)            (None, 1)                 17        \n",
      "                                                                 \n",
      "=================================================================\n",
      "Total params: 76,801\n",
      "Trainable params: 76,801\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model = create_model()\n",
    "# load the saved/trained weights\n",
    "model.load_weights(\"results/model.h5\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "6bd2286e",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\yzd\\AppData\\Local\\Temp\\ipykernel_25944\\4233457176.py:30: FutureWarning: Pass y=[3.0405903e-07 1.2997993e-04 3.0499854e-04 ... 4.3696558e-04 3.8402583e-04\n",
      " 3.7111889e-04] as keyword args. From version 0.10 passing these as positional arguments will result in an error\n",
      "  mel = np.mean(librosa.feature.melspectrogram(X, sr=sample_rate).T,axis=0)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1/1 [==============================] - 0s 172ms/step\n",
      "Result: female\n",
      "Probabilities::: Male: 34.88%    Female: 65.12%\n"
     ]
    }
   ],
   "source": [
    "file='let-it-go.wav'\n",
    "features = extract_feature(file, mel=True).reshape(1, -1)\n",
    "male_prob = model.predict(features)[0][0]\n",
    "female_prob = 1 - male_prob\n",
    "gender = \"male\" if male_prob > female_prob else \"female\"\n",
    "print(\"Result:\", gender)\n",
    "print(f\"Probabilities::: Male: {male_prob*100:.2f}%    Female: {female_prob*100:.2f}%\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "c9b74d09",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1/1 [==============================] - 0s 24ms/step\n",
      "Result: male\n",
      "Probabilities::: Male: 66.79%    Female: 33.21%\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\yzd\\AppData\\Local\\Temp\\ipykernel_25944\\4233457176.py:30: FutureWarning: Pass y=[-1.2089190e-05 -1.1194929e-05  2.2884158e-06 ...  1.1522309e-03\n",
      "  1.5081012e-03  1.9568861e-03] as keyword args. From version 0.10 passing these as positional arguments will result in an error\n",
      "  mel = np.mean(librosa.feature.melspectrogram(X, sr=sample_rate).T,axis=0)\n"
     ]
    }
   ],
   "source": [
    "file='zhan.wav'\n",
    "features = extract_feature(file, mel=True).reshape(1, -1)\n",
    "male_prob = model.predict(features)[0][0]\n",
    "female_prob = 1 - male_prob\n",
    "gender = \"male\" if male_prob > female_prob else \"female\"\n",
    "print(\"Result:\", gender)\n",
    "print(f\"Probabilities::: Male: {male_prob*100:.2f}%    Female: {female_prob*100:.2f}%\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3254a7a4",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d152e0ba",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
